package utils;

import java.util.Enumeration;
import java.util.Observable;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Vector;

import nanoxml.XMLElement;

import commands.Commands;
import enums.PlayerColor;

/**
 * A list of all the players
 */
public class PlayerList extends Observable implements ITransmittable  {

	private SortedMap<String, Player> players;
	private String currentPlayer;

	
	public PlayerList () {
		this.players = new TreeMap<String, Player> ();
	}
	
	public PlayerList (User user ) {
		this();
		players.put(user.getUsername(), new Player(user));
	}
	
	public PlayerList (PlayerList sourcePlayerList) {
		this();
		for (Player p : sourcePlayerList.getPlayers()) {
			this.players.put(p.getPlayerName(), new Player(p.getUser(), p.getColor()));
		}
		this.currentPlayer = sourcePlayerList.currentPlayer;
	}
	
	
	@SuppressWarnings("unchecked")
	public PlayerList (XMLElement message) {
		this();
		
		Enumeration<XMLElement> e = message.enumerateChildren();
		while (e.hasMoreElements()) {
			XMLElement childElement = e.nextElement();
			Player player = new Player (childElement);
			this.players.put (player.getPlayerName(), player);
		}
	}
	
	@Override
	public String toString()
	{
		String playersNamesListString = players.keySet().toString();
		
		// Return the list without the "[" and "]" that surround it when you perform .toString() on a Set
		return playersNamesListString.substring(1, playersNamesListString.length() - 1);
	}
	
	public XMLElement toXML () {
		XMLElement message = new XMLElement ();
		message.setName(Commands.PLAYER_LIST);
		// Add player children
		Vector<Player> vPlayers = getPlayers ();
		for (int i = 0; i < this.players.size(); i++) {
			Player player = (Player)vPlayers.get(i);
			message.addChild (player.toXML());
		}
		return message;
	}
	
	public boolean addPlayer (User theUser , PlayerColor color) {
		String playerName = theUser.getUsername();

		Player player = new Player (theUser , color);
		this.players.put (playerName, player);
		refreshObservers();
		return true;
	}

	public boolean addPlayer (User theUser) {
		String playerName = theUser.getUsername();

		Player player = new Player (theUser);
		this.players.put (playerName, player);
		refreshObservers();
		return true;
	}
	
	public boolean removePlayer (String playerName) {
	    if (this.players.remove (playerName) == null) {
		    return false;
	    }
	    refreshObservers();
		return true;
	}

	public int size () {
	    return this.players.size ();
	}

	public boolean isEmpty()
	{
		return players.isEmpty();
	}
	
	public boolean containsPlayer (String playerName) {
		return this.players.containsKey (playerName);
	}

	public Player getPlayer (String playerName) {
		return this.players.get(playerName);
	}

	public Vector<Player> getPlayers () {
		return new Vector<Player> (this.players.values());
	}

	public String getCurrentPlayerName () {
		return this.currentPlayer;
	}

	public Player getCurrentPlayer () {
		return this.players.get (this.currentPlayer);
	}

	public void refreshObservers() {
	    setChanged();
	    super.notifyObservers();
	}
}